﻿using System;
using System.Linq;
using Hxsoft.AppV1;

namespace Hxsoft.AppV1.Module
{
	public static class UserPermissions
	{
		#region GetUserIsHasCategoryPermission
		/// <summary>
		/// 获取用户是否有指定资源类别下的任何一项资源的指定权限。
		/// </summary>
		/// <param name="o">用户权限集合。</param>
		/// <param name="username">用户名。</param>
		/// <param name="categoryId">指定的资源类别。</param>
		/// <param name="permissionCode">指定的权限码。</param>
		/// <param name="siteId">权限的站点范围。</param>
		/// <returns>布尔值表示用户是否有指定资源类别下的任何一项资源的指定权限。</returns>
		public static bool GetUserIsHasCategoryPermission(this System.Data.Linq.Table<UserPermission> o, string username, Guid categoryId, int permissionCode, int? siteId)
		{
			var q = from p in o
					where p.IsEnabled == true
						&& p.CategoryId == categoryId
						&& p.PermissionCode == permissionCode
						&& p.UserName == username
					select p;

			if (siteId.HasValue)
				return q.Any(p => p.SiteId == siteId.Value || p.SiteId == null);
			return q.Any(p => p.SiteId == null);
		}

		/// <summary>
		/// 获取用户是否有指定资源类别下的任何一项资源的指定权限（不受站点限制）。
		/// </summary>
		/// <param name="o">用户权限集合。</param>
		/// <param name="username">用户名。</param>
		/// <param name="categoryId">指定的资源类别。</param>
		/// <param name="permissionCode">指定的权限码。</param>
		/// <returns>布尔值表示用户是否有指定资源类别下的任何一项资源的指定权限。</returns>
		public static bool GetUserIsHasCategoryPermission(this System.Data.Linq.Table<UserPermission> o, string username, Guid categoryId, int permissionCode)
		{
			var q = from p in o
					where p.IsEnabled == true
						&& p.CategoryId == categoryId
						&& p.PermissionCode == permissionCode
						&& p.UserName == username
					select p;

			return q.Any();
		}
		#endregion



		#region GetUserIsHasPermission
		/// <summary>
		/// 获取用户是否有指定的权限。
		/// </summary>
		/// <param name="o">用户权限集合。</param>
		/// <param name="username">用户名。</param>
		/// <param name="resourceId">资源标识。</param>
		/// <param name="permissionCode">权限码。</param>
		/// <param name="siteId">权限的站点范围。</param>
		/// <returns>布尔值表示用户是否有指定的权限。</returns>
		public static bool GetUserIsHasPermission(this System.Data.Linq.Table<UserPermission> o, string username, Guid resourceId, int permissionCode, int? siteId)
		{
			var q = from p in o
					where p.IsEnabled == true
						&& p.ResourceId == resourceId
						&& p.PermissionCode == permissionCode
						&& p.UserName == username
					select p;

			if (siteId.HasValue)
				return q.Any(p => p.SiteId == siteId.Value || p.SiteId == null);
			return q.Any(p => p.SiteId == null);
		}

		/// <summary>
		/// 获取用户是否有指定的权限（不受站点限制）。
		/// </summary>
		/// <param name="o">用户权限集合。</param>
		/// <param name="username">用户名。</param>
		/// <param name="resourceId">资源标识。</param>
		/// <param name="permissionCode">权限码。</param>
		/// <returns>布尔值表示用户是否有指定的权限。</returns>
		public static bool GetUserIsHasPermission(this System.Data.Linq.Table<UserPermission> o, string username, Guid resourceId, int permissionCode)
		{
			var q = from p in o
					where p.IsEnabled == true
						&& p.ResourceId == resourceId
						&& p.PermissionCode == permissionCode
						&& p.UserName == username
					select p;

			return q.Any();
		}
		#endregion



		/// <summary>
		/// 获取指定的用户是否拥有指定站点列表的任意一个的特定权限。
		/// </summary>
		/// <param name="o">用户权限集合。</param>
		/// <param name="username">用户名。</param>
		/// <param name="resourceId">资源标识。</param>
		/// <param name="permissionCode">权限码。</param>
		/// <param name="siteIds">权限的站点范围。</param>
		/// <returns>布尔值表示指定的用户是否拥有指定站点列表的任意一个的特定权限。</returns>
		public static bool GetUserIsHasAnySitePermission(this System.Data.Linq.Table<UserPermission> o, string username, Guid resourceId, int permissionCode, int[] siteIds)
		{
			if (GetUserIsHasPermission(o, username, resourceId, permissionCode, null)) return true;

			var q = from p in o
					where p.IsEnabled == true
						&& p.ResourceId == resourceId
						&& p.PermissionCode == permissionCode
						&& p.UserName == username
						&& (p.SiteId.HasValue && siteIds.Contains(p.SiteId.Value))
					select p;

			return q.Any();
		}



		/// <summary>
		/// 获取用户是否有指定的权限。（所有指定的站点）。
		/// </summary>
		/// <param name="o">用户权限集合。</param>
		/// <param name="username">用户名。</param>
		/// <param name="resourceId">资源标识。</param>
		/// <param name="permissionCode">权限码。</param>
		/// <param name="siteIds">权限的站点范围。</param>
		/// <returns>布尔值表示用户是否有指定的权限。</returns>
		public static bool GetUserIsHasEverySitePermission(this System.Data.Linq.Table<UserPermission> o, string username, Guid resourceId, int permissionCode, int[] siteIds)
		{
			if (GetUserIsHasPermission(o, username, resourceId, permissionCode, null)) return true;

			siteIds = siteIds.Distinct().ToArray();

			var q = from p in o
					where p.IsEnabled == true
						&& p.ResourceId == resourceId
						&& p.PermissionCode == permissionCode
						&& p.UserName == username
						&& (p.SiteId.HasValue && siteIds.Contains(p.SiteId.Value))
					group p by p.SiteId into g
					select g.Key;

			return siteIds.All(id => q.ToArray().Contains(id));
		}
	}
}